//	element.js

function Element() {
	this.x = 0;
	this.y = 0;

	this.widht = 0;
	this.hight = 0;

	this.connectors = [];
}

Element.prototype.constructor = Element;

//	Служит для опитсания портов элемента.
//	@param p Определяет область зацепления.
//	@return Индефикатор нового порта.
Element.prototype.addConnector = function(x, y, p, obj) {
	var port = {'x': x, 'y': y, 'p': p, 'obj': obj};
	console.log(this);

	this.connectors.push(port);

	return this.connectors.length - 1;
};

//
Element.prototype.getConnectorById = function(id) {
	return this.connectors[id];
};

//
Element.prototype.getConnectorByPoint = function(x, y) {
	for (var i = 0; i < this.connectors.length; i++) {
		port = this.connectors[i];
		min_x = port.x - port.p;
		max_x = port.x + port.p;

		min_y = port.y - port.p;
		max_y = port.y + port.p;

//		console.log('(' + min_x + ', ' + max_x +'); (' + min_y + ', ' + max_y + ')');

		if ((x >= min_x && x <= max_x) && (y >= min_y && y <= max_y)) {
			return port;
		}
	}

	return undefined;
};

Element.prototype.connectTo = function(x, y, obj) {
	var port = this.getConnectorByPoint(x, y);

	if (port) {
		port.obj = obj;
	}
};


function Wire() {
	Wire.superclass.constructor.apply(this, arguments);

	this.path = [];
	this.isPathBuilt = false;
	this.onBuilding = false;
}

extend(Wire, Element);

//	Функция перегружена.
//	1. Если аргументы не заданы, то рисуется весь путь.
//	2. Если задано два аргумента, то рисуется прямая от конектора до
//	указателя мыши. Т.е. по существу функция является обработчиком на
//	mouse-move
Wire.prototype.draw = function (x, y) {
	var context = document.getElementById("true_canvas").getContext("2d");

	if (arguments.length == 0 && this.path.length) {
		var x = this.path[0][0];
		var y = this.path[0][1];

		context.moveTo(x, y);

		for (var i = 1; i < this.path.length; i++) {
			context.lineTo(x, y);
		}
	}
	if (arguments.length == 2 && !this.isPathBuilt) {
		context.lineTo(x, y);
	}

	context.lineWidth = 3;
	context.stroke();
}

Wire.prototype.findPath = function () {
//	TODO: ?
}

Wire.prototype.from = function (x, y) {
	for (var e in scheme.elements) {
		var port = e.getConnectorByPoint(x, y);

		if (port) {
			x = port.x;
			y = port.y;

			this.onBuilding = false;
			this.isPathBuilt = false;
			this.path = [[x, y]];
			this.conntectors = [];
			this.addConnector(x, y, port.p);

			return true;
		}
	}

	scheme.stopCreation();

	return false;
}

//
//	Фактически является реализацией события mouse-up. При отжатии кнопки
//	мыши проверяется, что в окресности указателя есть порт при условии, что
//	существует начало провода. Если условия не выполнены, то линия исчезает.
//	Иначе фиксируется соединение и расчёт пути провода.
//	@param x Координата X указателя мыши.
//	@param y Координата Y указателя мыши.
Wire.prototype.to = function (x, y) {
	if (!this.connectors.length) {
//		TODO: 
		return;
	}

	for (var e in scheme.elements) {
		var port = e.getConnectorByPoint(x, y);

		if (port) {
			x = port.x;
			y = port.y;

			this.isPathBuilt = true;
			this.addConnector(x, y, port.p);
			this.findPath();
			
			scheme.register(this);
			scheme.stopCreation();

			return true;
		}
	}

	this.path.push([x, y]);

	return false;
}
